﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SimpleMap;
using SimpleMap.Extractors;
using SimpleMap.ClassFactories;
using SimpleMap.Setters;

namespace ClientDemo
{
    public partial class Form1 : Form
    {


        public Form1()
        {
            InitializeComponent();
        }

        private DataTable CreateDataTable(int rows)
        {
            DataTable myDataTable = new DataTable();

            DataColumn myDataColumn;

            myDataColumn = new DataColumn();
            myDataColumn.DataType = Type.GetType("System.Int32");
            myDataColumn.ColumnName = "id";
            myDataTable.Columns.Add(myDataColumn);

            myDataColumn = new DataColumn();
            myDataColumn.DataType = Type.GetType("System.Int32");
            myDataColumn.ColumnName = "user_id";
            myDataTable.Columns.Add(myDataColumn);

            myDataColumn = new DataColumn();
            myDataColumn.DataType = Type.GetType("System.String");
            myDataColumn.ColumnName = "name";
            myDataTable.Columns.Add(myDataColumn);


            myDataColumn = new DataColumn();
            myDataColumn.DataType = Type.GetType("System.String");
            myDataColumn.ColumnName = "column_6";
            myDataTable.Columns.Add(myDataColumn);

            myDataColumn = new DataColumn();
            myDataColumn.DataType = Type.GetType("System.Int32");
            myDataColumn.ColumnName = "sequence";
            myDataTable.Columns.Add(myDataColumn);


            for (int x = 0; x < rows; x++)
            {
                myDataTable.Rows.Add(new object[] { x, x + 10, string.Format("name {0}", x), string.Format("name {0}", x), 0 });

            }

            return myDataTable;
        }

        private void execute_Click_enum(object sender, EventArgs e)
        {

            try
            {
                this.Cursor = Cursors.WaitCursor;
                this.projectionGrid.DataSource = null;
                this.execute.Enabled = false;
                this.enum_execute.Enabled = false;

                DataTable table = this.CreateDataTable((int)this.numericUpDown1.Value);
                List<TargetClass> set = new List<TargetClass>();

                DateTime start = DateTime.Now;

                Projector<TargetClass> p = this.CreateProjector();

                int count = 0;

                foreach (TargetClass t in p.GetCursor(table.CreateDataReader()))
                {
                    count++;
                }


                DateTime end = DateTime.Now;

                MessageBox.Show(string.Format("Enumerated {0} rows in {1}sec", count, (end - start).TotalSeconds));


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                this.execute.Enabled = true;
                this.enum_execute.Enabled = true;
                this.Cursor = Cursors.Default;
            }



        }

        private void execute_Click(object sender, EventArgs e)
        {

            try
            {
                this.Cursor = Cursors.WaitCursor;

                this.execute.Enabled = false;
                this.enum_execute.Enabled = false;


                DataTable table = this.CreateDataTable((int)this.numericUpDown1.Value);
                List<TargetClass> set = new List<TargetClass>();

                DateTime start = DateTime.Now;

                Projector<TargetClass> p = this.CreateProjector();

                p.Project(set, table.CreateDataReader());

                DateTime end = DateTime.Now;

                this.projectionGrid.DataSource = set;
                MessageBox.Show(string.Format("Projected {0} rows in {1}sec", set.Count, (end - start).TotalSeconds));


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                this.execute.Enabled = true;
                this.enum_execute.Enabled = true;

                this.Cursor = Cursors.Default;
            }



        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            codeGen.Checked = numericUpDown1.Value > 1000;
        }

        private Projector<TargetClass> CreateProjector()
        {

            IPropertyValueSetterFactory<TargetClass> setterFactory = (IPropertyValueSetterFactory<TargetClass>)new PropertySetterValueFactory<TargetClass>(codeGen.Checked);

            if (customFactory.Checked)
            {
                CustomExtractor<TargetClass> ce = new CustomExtractor<TargetClass>(new PropertyBindingExtractor<TargetClass>(setterFactory));
                ce.ChangeBinding("column_6", x => x.name1);
                IValueBindingExtractor<TargetClass> extractor = (IValueBindingExtractor<TargetClass>)ce;
                IClassFactory<TargetClass> classFactory = new ClassFactory<TargetClass>();

                return new Projector<TargetClass>(extractor, classFactory);

            }
            else
            {
                return Projector<TargetClass>.CreateProjector(codeGen.Checked);
            }


        }




        /// <summary>
        /// Custom Factory 
        /// </summary>
        public class TargetFactory : IClassFactory<TargetClass>
        {

            #region IClassFactory<TargetClass> Members

            public TargetClass Create()
            {
                return new TargetClass();
            }

            #endregion
        }

    }


}
